/*************************************************************************************
 * @file    usart.c 
 *
 * @author  Shanon
 *
 * @date    02-08-2016
 *
 * @brief   usart source file.
 ************************************************************************************/
#include <stdio.h>
#include "stm32f4xx.h"
#include "usart.h"

#ifdef __GNUC__
  /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
     set to 'Yes') calls __io_putchar() */
  #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
  #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */

/*************************************************************************************
 * @func  USART1_Init
 *
 * @param[in]  none
 * @return  none
 *
 * @brief   Configure OPEN_USART.
 ************************************************************************************/
void USART1_Init( void )
{										
  GPIO_InitTypeDef  GPIO_InitStructure;
  USART_InitTypeDef  USART_InitStructure;
	
/*************************************************************************************
 * Enable GPIO peripheral clock
 ************************************************************************************/
  RCC_AHB1PeriphClockCmd( Open_USART1_TX_GPIO_CLK, ENABLE );
  RCC_AHB1PeriphClockCmd( Open_USART1_RX_GPIO_CLK, ENABLE );

/*************************************************************************************
 * Enable USART peripheral clock
 ************************************************************************************/
  RCC_APB2PeriphClockCmd( Open_USART1_CLK, ENABLE );
	
/*************************************************************************************
 * Configure alternative function
 ************************************************************************************/
  GPIO_PinAFConfig( Open_USART1_TX_GPIO_PORT, 
                    Open_USART1_TX_SOURCE, 
                    Open_USART1_TX_AF );
  GPIO_PinAFConfig( Open_USART1_RX_GPIO_PORT, 
                    Open_USART1_RX_SOURCE, 
                    Open_USART1_RX_AF );

/*************************************************************************************
 * Open_USART1_TX -> PA9 , Open_USART1_RX -PA10
 ************************************************************************************/
  GPIO_InitStructure.GPIO_Pin = Open_USART1_TX_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
	
  GPIO_Init( Open_USART1_TX_GPIO_PORT, &GPIO_InitStructure );

  GPIO_InitStructure.GPIO_Pin = Open_USART1_RX_PIN;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
	
  GPIO_Init( Open_USART1_RX_GPIO_PORT, &GPIO_InitStructure );

/*************************************************************************************
 * USARTx configured as follow:
 * BaudRate = 115200 baud  
 * Word Length = 8 Bits
 * One Stop Bit
 * No parity
 * Hardware flow control disabled (RTS and CTS signals)
 * Receive and transmit    
 ************************************************************************************/
  USART_InitStructure.USART_BaudRate = 115200;
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  USART_InitStructure.USART_StopBits = USART_StopBits_1;
  USART_InitStructure.USART_Parity = USART_Parity_No;
  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	
  USART_Init( Open_USART1, &USART_InitStructure );
	
  /* Enable the Open_USART Transmit interrupt: this interrupt is generated when the 
     Open_USART transmit data register is empty */
  USART_ITConfig( Open_USART1, USART_IT_RXNE, ENABLE );

  USART_Cmd( Open_USART1, ENABLE );
}
/*************************************************************************************
 * @func  USART1_NVIC_Config
 *
 * @param[in]  none
 * @return  none
 *
 * @brief   Configure USART1 interrupt.
 ************************************************************************************/
void USART1_NVIC_Config( void )
{
  NVIC_InitTypeDef  NVIC_InitStructure;

  /* Enable the USARTx Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = Open_USART1_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x2;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	
  NVIC_Init( &NVIC_InitStructure );
}

/*************************************************************************************
 * @func  USART1_Init
 *
 * @param[in]  none
 * @return  none
 *
 * @brief   Configure OPEN_USART.
 ************************************************************************************/
void USART2_Init( void )
{										
  GPIO_InitTypeDef  GPIO_InitStructure;
  USART_InitTypeDef  USART_InitStructure;
	
/*************************************************************************************
 * Enable GPIO peripheral clock
 ************************************************************************************/
  RCC_AHB1PeriphClockCmd( Open_USART2_TX_GPIO_CLK, ENABLE );
  RCC_AHB1PeriphClockCmd( Open_USART2_RX_GPIO_CLK, ENABLE );

/*************************************************************************************
 * Enable USART peripheral clock
 ************************************************************************************/
  RCC_APB1PeriphClockCmd( Open_USART2_CLK, ENABLE );
	
/*************************************************************************************
 * Configure alternative function
 ************************************************************************************/
  GPIO_PinAFConfig( Open_USART2_TX_GPIO_PORT, 
                    Open_USART2_TX_SOURCE, 
                    Open_USART2_TX_AF );
  GPIO_PinAFConfig( Open_USART2_RX_GPIO_PORT, 
                    Open_USART2_RX_SOURCE, 
                    Open_USART2_RX_AF );

/*************************************************************************************
 * Open_USART1_TX -> PA9 , Open_USART1_RX -PA10
 ************************************************************************************/
  GPIO_InitStructure.GPIO_Pin = Open_USART2_TX_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
	
  GPIO_Init( Open_USART2_TX_GPIO_PORT, &GPIO_InitStructure );

  GPIO_InitStructure.GPIO_Pin = Open_USART2_RX_PIN;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
	
  GPIO_Init( Open_USART2_RX_GPIO_PORT, &GPIO_InitStructure );

/*************************************************************************************
 * USARTx configured as follow:
 * BaudRate = 115200 baud  
 * Word Length = 8 Bits
 * One Stop Bit
 * No parity
 * Hardware flow control disabled (RTS and CTS signals)
 * Receive and transmit    
 ************************************************************************************/
  USART_InitStructure.USART_BaudRate = 9600;
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  USART_InitStructure.USART_StopBits = USART_StopBits_1;
  USART_InitStructure.USART_Parity = USART_Parity_No;
  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	
  USART_Init( Open_USART2, &USART_InitStructure );
	
  /* Enable the Open_USART Transmit interrupt: this interrupt is generated when the 
     Open_USART transmit data register is empty */
  USART_ITConfig( Open_USART2, USART_IT_RXNE, ENABLE );

  USART_Cmd( Open_USART2, ENABLE );
}
/*************************************************************************************
 * @func  USART2_NVIC_Config
 *
 * @param[in]  none
 * @return  none
 *
 * @brief   Configure USART2 interrupt.
 ************************************************************************************/
void USART2_NVIC_Config( void )
{
  NVIC_InitTypeDef  NVIC_InitStructure;

  /* Enable the USARTx Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = Open_USART2_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	
  NVIC_Init( &NVIC_InitStructure );
}

/*************************************************************************************
 * @func  USART1_Init
 *
 * @param[in]  none
 * @return  none
 *
 * @brief   Configure OPEN_USART.
 ************************************************************************************/
void USART3_Init( void )
{										
  GPIO_InitTypeDef  GPIO_InitStructure;
  USART_InitTypeDef  USART_InitStructure;
  
/*************************************************************************************
 * Enable GPIO peripheral clock
 ************************************************************************************/
  RCC_AHB1PeriphClockCmd( Open_USART3_TX_GPIO_CLK, ENABLE );
  RCC_AHB1PeriphClockCmd( Open_USART3_RX_GPIO_CLK, ENABLE );

/*************************************************************************************
 * Enable USART peripheral clock
 ************************************************************************************/
  RCC_APB1PeriphClockCmd( Open_USART3_CLK, ENABLE );
	
/*************************************************************************************
 * Configure alternative function
 ************************************************************************************/
  GPIO_PinAFConfig( Open_USART3_TX_GPIO_PORT, 
                    Open_USART3_TX_SOURCE, 
                    Open_USART3_TX_AF );
  GPIO_PinAFConfig( Open_USART3_RX_GPIO_PORT, 
                    Open_USART3_RX_SOURCE, 
                    Open_USART3_RX_AF );

/*************************************************************************************
 * Open_USART1_TX -> PA9 , Open_USART1_RX -PA10
 ************************************************************************************/
  GPIO_InitStructure.GPIO_Pin = Open_USART3_TX_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
	
  GPIO_Init( Open_USART3_TX_GPIO_PORT, &GPIO_InitStructure );

  GPIO_InitStructure.GPIO_Pin = Open_USART3_RX_PIN;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
	
  GPIO_Init( Open_USART3_RX_GPIO_PORT, &GPIO_InitStructure );

/*************************************************************************************
 * USARTx configured as follow:
 * BaudRate = 115200 baud  
 * Word Length = 8 Bits
 * One Stop Bit
 * No parity
 * Hardware flow control disabled (RTS and CTS signals)
 * Receive and transmit    
 ************************************************************************************/
  USART_InitStructure.USART_BaudRate = 9600;
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  USART_InitStructure.USART_StopBits = USART_StopBits_1;
  USART_InitStructure.USART_Parity = USART_Parity_No;
  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	
  USART_Init( Open_USART3, &USART_InitStructure );
	
  /* Enable the Open_USART Transmit interrupt: this interrupt is generated when the 
     Open_USART transmit data register is empty */
  USART_ITConfig( Open_USART3, USART_IT_RXNE, ENABLE );

  USART_Cmd( Open_USART3, ENABLE );
}
/*************************************************************************************
 * @func  USART1_NVIC_Config
 *
 * @param[in]  none
 * @return  none
 *
 * @brief   Configure USART1 interrupt.
 ************************************************************************************/
void USART3_NVIC_Config( void )
{
  NVIC_InitTypeDef  NVIC_InitStructure;

  /* Enable the USARTx Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = Open_USART3_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	
  NVIC_Init( &NVIC_InitStructure );
}

/* Use no semihosting */
#if 1
#pragma import(__use_no_semihosting)
struct __FILE 
{  
	int handle;
};
FILE __stdout;

void _sys_exit(int x)
{
	x = x;
}
#endif

/*************************************************************************************
 * @brief  Retargets the C library printf function to the USART.
 *
 * @param[in]  None
 *
 * @return  None
 ************************************************************************************/
PUTCHAR_PROTOTYPE
{
  /* Place your implementation of fputc here */
  /* e.g. write a character to the USART */
  USART_SendData( Open_USART1, (uint8_t) ch );
  /* Loop until the end of transmission */
  while ( USART_GetFlagStatus( Open_USART1, USART_FLAG_TC ) == RESET ){}
  return ch;
}
